package top.lingkang.finalgateway.admin.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.DownloadedFile;
import org.noear.solon.core.handle.MethodType;
import org.noear.solon.core.handle.UploadedFile;
import top.lingkang.finalgateway.admin.dto.ResponseResult;
import top.lingkang.finalgateway.admin.entity.SystemDataEntity;
import top.lingkang.finalgateway.admin.mapper.SystemDataMapper;
import top.lingkang.finalgateway.admin.vo.FileListVO;
import top.lingkang.finalgateway.utils.StaticMimes;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

/**
 * @author lingkang
 * Created by 2024/5/19
 */
@Controller
@Mapping("/api/dir")
@Slf4j
public class DirController {
    @Inject
    private SystemDataMapper systemDataMapper;

    @Mapping(value = "/list", method = MethodType.GET)
    public Object list(String path, Boolean up, Context context) throws Exception {
        File file = null;
        if (StrUtil.isNotBlank(path)) {
            path = URLUtil.decode(path);
            file = new File(path);
            if (!file.exists())
                return new ResponseResult<>().fail("路径错误或不存在: " + path);
        } else {
            SystemDataEntity entity = systemDataMapper.selectById("lastPath");
            if (entity != null) {
                file = new File(entity.getData());
            } else {
                file = new File(System.getProperty("user.home"));
                savePath(file.getAbsolutePath());
            }
        }

        if (up != null && up) {
            file = file.getParentFile();
            if (file == null)
                return new ResponseResult<>().fail("已经是最上层目录了");
        }

        if (file.isDirectory()) {
            savePath(file.getAbsolutePath());
            File[] files = file.listFiles();
            List<FileListVO> list = new ArrayList<>();
            if (files != null) {
                String current = file.getAbsolutePath();
                String parent = file.getParent();
                if (parent == null) {
                }
                for (File f : files) {
                    FileListVO vo = new FileListVO();
                    vo.setName(f.getName());
                    vo.setPath(f.getAbsolutePath());
                    vo.setCurrent(current);
                    vo.setDir(f.isDirectory());
                    vo.setLastModified(f.lastModified());
                    vo.setSize(f.length());
                    vo.setParent(parent);
                    list.add(vo);
                }
            }
            list.sort((o1, o2) -> {
                return o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase());
            });
            return new ResponseResult<>(list);
        } else {
            return new ResponseResult<>().fail("这是一个文件，无法打开");
        }
    }

    @Mapping(value = "/open", method = MethodType.GET)
    public Object open(String path, Context context) throws Exception {
        Assert.notBlank(path, "路径不能为空");

        File file = new File(path);
        if (!file.exists()) {
            context.outputAsJson(new ResponseResult<>().fail("文件不存在").toString());
            return null;
        } else if (file.isDirectory()) {
            context.outputAsJson(new ResponseResult<>().fail("不能打开目录").toString());
            return null;
        }

        // 下载或打开文件
        String type = StaticMimes.get(("." + FileUtil.getSuffix(file)).toLowerCase());
        if (type != null && file.length() < 8388608) {// 8MB以内
            context.contentType(type);
            type = type.toLowerCase();
            if (type.contains("text") || type.contains("image") || type.contains("xml"))
                context.output(Files.newInputStream(file.toPath()));
            else
                context.outputAsFile(file);
        } else {
            // 最后直接输出文件
            return new DownloadedFile(file);
        }
        return null;
    }

    @Mapping(value = "/download", method = MethodType.GET)
    public Object download(String path, Context context) throws IOException {
        Assert.notBlank(path, "路径不能为空");

        File file = new File(path);
        if (!file.exists()) {
            context.outputAsJson(new ResponseResult<>().fail("文件不存在").toString());
            return null;
        } else if (file.isDirectory()) {
            context.outputAsJson(new ResponseResult<>().fail("不能下载目录").toString());
            return null;
        }
        // 下载文件
        return new DownloadedFile(file);
    }

    @Mapping(value = "/delete", method = MethodType.POST)
    public Object delete(String path) {
        Assert.notBlank(path, "路径不能为空");
        File file = new File(path);
        if (!file.exists()) {
            return new ResponseResult<>().fail("文件或目录不存在");
        }
        FileUtil.del(file);
        return new ResponseResult<>().ok();
    }

    @Mapping(value = "/upload", method = MethodType.POST)
    public Object upload(String path, UploadedFile file) {
        Assert.notBlank(path, "路径不能为空");
        Assert.notNull(file, "上传文件不能为空");
        File dir = new File(path);
        Assert.isTrue(dir.exists() && dir.isDirectory(), "路径不存在或路径不是目录");
        File newFile = new File(dir.getAbsolutePath() + File.separator + file.getName());
        int i = 1;
        // 如果存在同名
        while (newFile.exists()) {
            newFile = new File(dir.getAbsolutePath() + File.separator + i + "-" + file.getName());
            i++;
        }
        try {
            file.transferTo(newFile);
        } catch (Exception e) {
            log.error("上传文件失败", e);
            return new ResponseResult<>().fail("上传文件失败: " + e.getMessage());
        } finally {
            try {
                file.delete();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return new ResponseResult<>().ok("上传成功", newFile.getName());
    }

    private void savePath(String path) {
        SystemDataEntity entity = systemDataMapper.selectById("lastPath");
        if (entity == null) {
            entity = new SystemDataEntity();
            entity.setName("lastPath");
            entity.setRemark("最后访问的目录路径");
            entity.setData(path);
            systemDataMapper.insert(entity);
            return;
        }
        entity.setData(path);
        systemDataMapper.updateById(entity);
    }
}
